    .text
    .extern kernel_init
    .extern init_main
    .global _start
_start:
    //取参数
    mov 4(%esp),%eax
    //传参数
    push %eax
    //函数调用
    call kernel_init

    jmp $8,$gdt_reload
gdt_reload:
    //修改段寄存器
    mov $16,%ax
    mov %ax, %ds
	mov %ax, %ss
	mov %ax, %es
	mov %ax, %fs
	mov %ax, %gs

    mov $stack, %eax
    add $1024*8, %eax
    mov %eax, %esp

    jmp init_main
    .bss
.comm stack,(1024*8)

.macro exception_handler name num with_err_code
    .text
    .extern do_handler_\name
    .global exception_handler_\name
exception_handler_\name:
    //保存寄存器
    .if \with_err_code==0
        push $0
    .endif
    push $\num
    pusha
    push %ds
    push %es
    push %fs
    push %gs

    push %esp
    call do_handler_\name
    pop %esp
    pop %gs
    pop %fs
    pop %es
    pop %ds
    popa

    add $(2*4) , %esp

    iret
.endm

exception_handler unknown,-1,0
exception_handler divzero,0,0
exception_handler Debug, 1, 0
exception_handler NMI, 2, 0
exception_handler breakpoint, 3, 0
exception_handler overflow, 4, 0
exception_handler bound_range, 5, 0
exception_handler invalid_opcode, 6, 0
exception_handler device_unavailable, 7, 0
exception_handler double_fault, 8, 1
exception_handler invalid_tss, 10, 1
exception_handler segment_not_present, 11, 1
exception_handler stack_segment_fault, 12, 1
exception_handler general_protection, 13, 1
exception_handler page_fault, 14, 1
exception_handler fpu_error, 16, 0
exception_handler alignment_check, 17, 1
exception_handler machine_check, 18, 0
exception_handler smd_exception, 19, 0
exception_handler virtual_exception, 20, 0

exception_handler time, 0x20, 0
exception_handler kbd, 0x21, 0
exception_handler ide_primary 0x2E,0


    //simple_switch(&from->stack,to->stack)
    .text
    .global simple_switch
 simple_switch:
    //from栈
    mov  4(%esp) , %eax     
    mov  8(%esp) , %edx     
    push %ebp
    push %ebx
    push %esi
    push %edi
    mov %esp,(%eax)       //eax -> &from->stack 保存当前栈指针        
    //切换 
    mov  %edx,%esp          
    //to栈
    pop %edi               
    pop %esi
    pop %ebx
    pop %ebp

    ret  
    
    .extern do_handler_syscall
    .global exception_handler_syscall
exception_handler_syscall:
    pusha
    push %ds
    push %es
    push %fs
    push %gs
    pushf

    mov  %esp,%eax
    push %eax
    call do_handler_syscall 
    add $4,%esp

    popf
    pop %gs
    pop %fs
    pop %es
    pop %ds
    popa

    retf $(5*4)